--[[
  import work like require, but support relative path.
  @function import
  @param string moduleName
  @param string currentModuleName
  @return mixed

  example:
  -->>>>>>> use import at module level <<<<<<--
  local data = import(".data") -- data.lua is in the same directory of the file.

  -->>>>>>> use import at function level <<<<<<--
  local CURRENT_MODULE_NAME = ...    -- get module name at module level
  local function testLoad()
    local MyClassBase = import(".MyClassBase", CURRENT_MODULE_NAME) -- pass module name
  end
]]--
  function import(moduleName, currentModuleName)
    local currentModuleNameParts
    local moduleFullName = moduleName
    local offset = 1

    while true do
        if string.byte(moduleName, offset) ~= 46 then -- .
            moduleFullName = string.sub(moduleName, offset)
            if currentModuleNameParts and #currentModuleNameParts > 0 then
                moduleFullName = table.concat(currentModuleNameParts, ".") .. "." .. moduleFullName
            end
            break
        end
        offset = offset + 1

        if not currentModuleNameParts then
            if not currentModuleName then
                local n,v = debug.getlocal(3, 1)
                currentModuleName = v
            end

            currentModuleNameParts = string.split(currentModuleName, ".")
        end
        table.remove(currentModuleNameParts, #currentModuleNameParts)
    end

    return require(moduleFullName)
end

--[[
  Auto create a anonymous function to make a callback handler.
  @function handler
  @param mixed obj
  @param function method
  @return function

  example:
  -- usually to convert a class' member function to be a handler
  self:addNodeEventListener(cc.ENTER_FRAME_EVENT, handler(self, self.onEnterFrame))
]]--
function handler(obj, method)
    return function(...)
        return method(obj, ...)
    end
end

---类函数
---@param classname string
---@return table
function class(classname, ...)
    local cls = {__cname = classname}
    local supers = {...}
    for _,super in ipairs(supers) do
        local superType = type(super)
        if superType == "table" then
            cls.__supers = cls.__supers or {}
            cls.__supers[#cls.__supers + 1] = super
            if not cls.super then
                cls.super = super
            end
        end
    end
    cls.__index = cls
    local mt
    if not cls.__supers or #cls.__supers == 1 then
        mt = {__index = cls.super}
    else
        mt = {__index = function (_, key)
            local supers = cls.__supers
            for i = 1, #supers do
                local super = supers[i]
                if super[key] then
                    return super[key]
                end
            end
        end}
    end
    mt.__call = function(cls, ...)
        local instance = setmetatable({}, cls)
        instance.class = cls
        instance:_init(...)
        return instance
    end
    setmetatable(cls, mt)
    return cls
end